import simpy
import random
import time

class Airplane:
    """ 航班类
    """
    def __init__(
            self, env, id, 
            land_at_airport,
            average_landing_time=35,
            average_takeoff_time=35,
            average_service_time=45*60
            ):
        
        self.env = env

        self.id = id

        self.arrival_time = self.env.now
        self.landing_wait_time = None
        self.takeoff_time = None
        self.stay_time = None
        
        # 按照《机场时刻容量评估技术规范》：
        # “空管单位提供统计数据，
        # 如没有统计数据，则由评
        # 估单位现场采集。”
        # 我们什么也没有，所以估值 120

        self.time_for_landing = max(
            # 起飞航空器从等待位置到对正跑道时间应控制在 50s 以内
            # 
            20, # 时间范围限制
            min(
                random.expovariate(
                    1 / (
                        average_landing_time) # 换算为分钟
                    ),
                60
                )
        )
        
        self.time_to_takeoff = max(  
            20,
            min(
                random.expovariate(
                    1 / (
                        average_takeoff_time)
                    ),
                60
                )
            )
        
        self.service_time = max(
            40 * 60,
            min(
                random.expovariate(
                    1 / (
                        average_service_time)
                    ),
                60 * 60
                )
            )

        self.land_at_airport = land_at_airport

        self.is_left = False

    def process(self):
        self.env.process(self.landing())

    def landing(self):
        print(
            self.id, 
            "is ready to land at", 
            time.strftime(
                  "%H:%M:%S", 
                  time.gmtime(self.env.now)
                )
            )

        with self.land_at_airport.runways.request(priority=0) as req:
            yield req
            # yield self.env.timeout(1 / 25)
            yield self.env.timeout(self.time_for_landing)
            print(
                self.id, 
                "landed at time", 
                time.strftime(
                  "%H:%M:%S", 
                  time.gmtime(self.env.now)
                  )
                )

            self.land_at_airport.taxi_way_system.count_airplane += 1
            
            self.env.process(self.parking())
    
    def parking(self):
        with self.land_at_airport.parking_bays.request(
            ) as req:
            yield req
            
            self.landing_wait_time = (
                self.env.now - self.arrival_time
                )
            
            with self.land_at_airport.ground_services_groups.request(
                ) as req:
                
                yield req
                
                yield self.env.timeout(self.service_time)  
                
                self.land_at_airport.taxi_way_system.count_airplane -= 1
                self.env.process(self.take_off())
            
    def take_off(self):
        print(
            self.id, 
            "is ready to take off at time", 
            time.strftime(
                  "%H:%M:%S", 
                  time.gmtime(self.env.now)
                )
            )

        with self.land_at_airport.runways.request(
                priority=1) as req:
            yield req
            yield self.env.timeout(
                self.time_to_takeoff
            )
            self.takeoff_time = self.env.now
            self.wait_time = self.takeoff_time - self.arrival_time 
            self.is_left = True

            print(
                self.id, 
                "took off at time", 
                time.strftime(
                  "%H:%M:%S", 
                  time.gmtime(self.env.now)
                  )
            )
    

    